//package io.github.novaframe.config.metrics;
//
//import com.codahale.metrics.JmxReporter;
//import com.codahale.metrics.MetricRegistry;
//import com.codahale.metrics.Slf4jReporter;
//import com.codahale.metrics.health.HealthCheckRegistry;
//import com.codahale.metrics.jvm.*;
//import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
//import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;
//import com.zaxxer.hikari.HikariDataSource;
//import io.github.novaframe.config.NovaframeProperties;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.actuate.metrics.reader.MetricReader;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
//import javax.annotation.PostConstruct;
//import java.lang.management.ManagementFactory;
//import java.util.concurrent.TimeUnit;
//
//@Configuration
//@ConditionalOnClass({ MetricReader.class, MetricRegistry.class})
//@EnableMetrics(proxyTargetClass = true)
//public class MetricsConfiguration extends MetricsConfigurerAdapter {
//
//    private static final String PROP_METRIC_REG_JVM_MEMORY = "jvm.memory"; // 内存
//    private static final String PROP_METRIC_REG_JVM_GARBAGE = "jvm.garbage"; // 垃圾回收
//    private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads"; // 线程
//    private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files";
//    private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers";
//    private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class);
//
//    private MetricRegistry metricRegistry = new MetricRegistry();
//
//    private HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
//
//    private final NovaframeProperties properties;
//
//    private HikariDataSource hikariDataSource;
//
//    public MetricsConfiguration(NovaframeProperties properties) {
//        this.properties = properties;
//    }
//
//    @Autowired(required = false)
//    public void setHikariDataSource(HikariDataSource hikariDataSource) {
//        this.hikariDataSource = hikariDataSource;
//    }
//
//    @Override
//    @Bean
//    public MetricRegistry getMetricRegistry() {
//        return metricRegistry;
//    }
//
//    @Override
//    @Bean
//    public HealthCheckRegistry getHealthCheckRegistry() {
//        return healthCheckRegistry;
//    }
//
//    @PostConstruct
//    public void init() {
//
//        /**
//         * 五种 Metrics 类型（http://wuchong.me/blog/2015/08/01/getting-started-with-metrics/）
//         * - Gauges：最简单的度量指标，只有一个简单的返回值，例如，我们想衡量一个待处理队列中任务的个数
//         * - Counters：Counter 就是计数器，Counter 只是用 Gauge 封装了 AtomicLong 。
//         * - Meters：Meter度量一系列事件发生的速率(rate)，例如TPS。
//         * - Histograms：Histogram统计数据的分布情况。比如最小值，最大值，中间值，还有中位数，75百分位, 90百分位, 95百分位, 98百分位, 99百分位, 和 99.9百分位的值(percentiles)。
//         */
//
//        /**
//         * MetricRegistry类
//         * 是Metrics的核心，它是存放应用中所有metrics的容器。也是我们使用 Metrics 库的起点。
//         */
//        log.debug("Registering JVM gauges");
//        metricRegistry.register(PROP_METRIC_REG_JVM_MEMORY, new MemoryUsageGaugeSet());
//        metricRegistry.register(PROP_METRIC_REG_JVM_GARBAGE, new GarbageCollectorMetricSet());
//        metricRegistry.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet());
//        metricRegistry.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge());
//        metricRegistry.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
//
//        if (hikariDataSource != null) {
//            log.debug("Monitoring the datasource");
//            hikariDataSource.setMetricRegistry(metricRegistry);
//        }
//
//        /**
//         * Metrics 数据展示
//         * Metircs 提供了 Report 接口，用于展示 metrics 获取到的统计数据。metrics-core中主要实现了四种 reporter： JMX, console, SLF4J, 和 CSV。
//         */
//        if (properties.getMetrics().getJmx().isEnabled()) {
//            log.debug("Initializing Metrics JMX reporting");
//            JmxReporter jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
//            jmxReporter.start();
//        }
//
//        if (properties.getMetrics().getLogs().isEnabled()) {
//            log.info("Initializing Metrics Log reporting");
//            final Slf4jReporter reporter = Slf4jReporter.forRegistry(metricRegistry)
//                .outputTo(LoggerFactory.getLogger("metrics"))
//                .convertRatesTo(TimeUnit.SECONDS)
//                .convertDurationsTo(TimeUnit.MILLISECONDS)
//                .build();
//            reporter.start(properties.getMetrics().getLogs().getReportFrequency(), TimeUnit.SECONDS);
//        }
//    }
//
//    /* Spectator metrics log reporting */
//    //@Bean
//    //@ConditionalOnProperty("novaframe.logging.spectator-metrics.enabled")
//    //@ExportMetricReader
//    //public SpectatorMetricReader SpectatorMetricReader(Registry registry) {
//    //    log.info("Initializing Spectator Metrics Log reporting");
//    //    return new SpectatorMetricReader(registry);
//    //}
//
//    //@Bean
//    //@ConditionalOnProperty("novaframe.logging.spectator-metrics.enabled")
//    //@ExportMetricWriter
//    //MetricWriter metricWriter() {
//    //    return new SpectatorLogMetricWriter();
//    //}
//}
